package main;

import nivel.Casillero;
import nivel.Nivel;

/**
 * Clase que modela como un controlador de el resto de los hilos involucrados en
 * la aplicacion. Se encarga de iniciar los hilos del programa.
 * 
 * @author Agustin Orge (LU.85538)
 * @author Victoria Martinez de la Cruz (LU.87620)
 */
public class ControlMain implements Runnable {
	/** El nivel */
	private Nivel nivel;
	/** Condicion de corte del bucle */
	private boolean terminarThread;
	/** Hilos */
	private Thread enemigos, monedas, powerups, disparos;

	/**
	 * Constructor del control
	 * 
	 * @param n
	 *            - nivel asociado
	 */
	public ControlMain(Nivel n) {
		nivel = n;
		terminarThread = false;
		enemigos = new Thread(nivel.getDirectorEnemigos());
		enemigos.start();

		monedas = new Thread(nivel.getControladorMonedas());
		monedas.start();

		powerups = new Thread(nivel.getDirectorPowerUps());
		powerups.start();

		disparos = new Thread(nivel.getControladorDisparos());
		disparos.start();

	}

	/**
	 * Metodo utilizado para controlar las colisiones entre mario y los power
	 * ups estaticos
	 */
	private void controlColisionPowerUpEstatico() {

		Casillero cActual = nivel.getTablero().buscarCasillero(
				nivel.getMario().getCasilleroActual().getX(),
				nivel.getMario().getCasilleroActual().getY());
		Casillero cIzq = nivel.getTablero().buscarCasillero(
				nivel.getMario().getCasilleroActual().getX() - 8,
				nivel.getMario().getCasilleroActual().getY());
		Casillero cDer = nivel.getTablero().buscarCasillero(
				nivel.getMario().getCasilleroActual().getX() + 8,
				nivel.getMario().getCasilleroActual().getY());

		if (cActual != null) {

			if (cActual.hayPowerUp()) {
				cActual.getPowerUp().agarrar();
			}
		} else if (cIzq != null) {

			if (cIzq.hayPowerUp()) {
				cIzq.getPowerUp().agarrar();
			}
		} else if (cDer != null) {

			if (cDer.hayPowerUp()) {
				cDer.getPowerUp().agarrar();
			}

			if (nivel.getMario().cantPowerUps() > 0) {
				controlPowerUpEstaticoMarioGrande();
			}
		}
	}

	/**
	 * Metodo especifico de control de colisiones para cuando mario ocupa dos
	 * casilleros
	 */
	private void controlPowerUpEstaticoMarioGrande() {
		Casillero cActual = nivel.getTablero().buscarCasillero(
				nivel.getMario().getCasilleroActual().getX(),
				nivel.getMario().getCasilleroActual().getY() - 16);
		Casillero cIzq = nivel.getTablero().buscarCasillero(
				nivel.getMario().getCasilleroActual().getX() - 8,
				nivel.getMario().getCasilleroActual().getY() - 16);
		Casillero cDer = nivel.getTablero().buscarCasillero(
				nivel.getMario().getCasilleroActual().getX() + 8,
				nivel.getMario().getCasilleroActual().getY() - 16);

		if (cActual != null) {

			if (cActual.hayPowerUp()) {
				cActual.getPowerUp().agarrar();
			}
		} else if (cIzq != null) {

			if (cIzq.hayPowerUp()) {
				cIzq.getPowerUp().agarrar();
			}
		} else if (cDer != null) {

			if (cDer.hayPowerUp()) {
				cDer.getPowerUp().agarrar();
			}
		}
	}

	@Override
	public void run() {
		while (!terminarThread) {

			synchronized (this) {

				nivel.getDirectorEnemigos().controlarColisiones();
				nivel.getDirectorPowerUps().controlarColisiones();
				controlColisionPowerUpEstatico();
				nivel.getMario().resetInvulnerabilidadTemporal();

			}

			try {
				Thread.sleep(50);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

	}

	/**
	 * Metodo que termina el bucle del metodo run()
	 */
	public void terminarHilo() {
		terminarThread = true;

	}

}
